﻿#include "GetConfig.h"
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <vector>

static void Rtrim(char* string)
{
	if (string == NULL)
		return;
	size_t len = strlen(string);
	int index = --len;
	while (len > 0 && string[index] == ' ')
		string[index--] = 0;
	return;
}

static void Ltrim(char* string)
{
	size_t len = strlen(string);
	char* ptemp = string;
	if (*ptemp != ' ')
	{// 不是以空格开头
		return;
	}

	while (*ptemp != '\0')
	{
		if (*ptemp == ' ')
			++ptemp;
		else
			break;
	}

	if (*ptemp == '\0')
	{// 全都是空格
		*string = '\0';
		return;
	}

	// 将第一个指针后面所指的内容移到前面来
	char* ptemp2 = string;
	while (*ptemp != '\0')
	{
		*ptemp2 = *ptemp;
		++ptemp;
		++ptemp2;
	}

	// 将结尾赋值位结束符
	*ptemp2 = '\0';
	return;
}


// 配置类静态实例初始化位空
CConfig* CConfig::m_instance = NULL;

CConfig::CConfig()
{

}

CConfig::~CConfig()
{
	std::vector<LPCConfItem>::iterator iter;
	for (iter = m_configItemList.begin(); iter != m_configItemList.end(); ++iter)
	{
		delete *iter;
	}
	m_configItemList.clear();
}

bool CConfig::Load(const char* pConfigName)
{
	FILE* fp = fopen(pConfigName, "r");
	if (fp == NULL)
	{
		return false;
	}

	// 每一行的配置文件读取出来都在这里
	char linebuf[512] = { 0 };

	while (!feof(fp))
	{
		if (fgets(linebuf, 511, fp) == NULL)
		{// 读取到结尾
			continue;
		}
		if (linebuf[0] == 0)
		{// 读取到的第一个字符是字符串结尾标志(\0)
			continue;
		}
		if (*linebuf == ';' || *linebuf == ' ' || *linebuf == '#' || *linebuf == '\t' || *linebuf == '\n' || *linebuf == '[')
		{// 如果读取的第一个字符是; 空格 # \t \n 直接掠过
			continue;
		}
		// 切除尾部多余字符的循环标签，用goto回到这里
	processsubstring:
		int nLen = strlen(linebuf);
		if (nLen > 0)
		{// 如果这一行经过处理后还有字符的话
			// 在这一行尾部 换行 回车 或者 空格 等都要截掉
			if (linebuf[nLen - 1] == 10 || linebuf[nLen - 1] == 13 || linebuf[nLen - 1] == 32)
			{
				linebuf[nLen - 1] = 0;
				goto processsubstring;
			}
			if (linebuf[0] == 0)
			{// 经过处理后变成了空行
				continue;
			}
			if (linebuf[0] == '[')
			{// 配置组信息也不处理
				continue;
			}

			// 找出=分割字符串
			char* ptemp = strchr(linebuf, '=');
			if (ptemp != NULL)
			{// 找到了=的配置行才算作有效
				LPCConfItem pConfItem = new CConfItem;
				memset(pConfItem, 0, sizeof(CConfItem));
				// 将等号左边的拷贝到配置项名(右边的减法是用等号的地址减去行配置的第一个的地址)
				strncpy(pConfItem->ItemName, linebuf, (int)(ptemp - linebuf));
				// 将等号右边的拷贝到配置项内容
				strcpy(pConfItem->ItemContent, ptemp + 1);

				// 切掉所有的空格
				Ltrim(pConfItem->ItemName);
				Rtrim(pConfItem->ItemName);
				Ltrim(pConfItem->ItemContent);
				Rtrim(pConfItem->ItemContent);

				m_configItemList.push_back(pConfItem);
			}
		}
	}
	fclose(fp);
	return true;
}

char* CConfig::GetString(const char* pItemName)
{
	std::vector<LPCConfItem>::iterator iter;
	for (iter = m_configItemList.begin(); iter != m_configItemList.end(); ++iter)
	{
#ifndef _WIN32
		if (strcasecmp((*iter)->ItemName, pItemName) == 0)
#else
		if (stricmp((*iter)->ItemName, pItemName) == 0)
#endif
		{
			return (*iter)->ItemContent;
		}
	}
	return NULL;
}

int CConfig::GetIntDefault(const char* pItemName, const int def)
{
	std::vector<LPCConfItem>::iterator iter;
	for (iter = m_configItemList.begin(); iter != m_configItemList.end(); ++iter)
	{
#ifndef _WIN32
		if (strcasecmp((*iter)->ItemName, pItemName) == 0)
#else
		if (stricmp((*iter)->ItemName, pItemName) == 0)
#endif
		{
			return atoi((*iter)->ItemContent);
		}
	}
	return def;
}

void CConfig::show()
{
	std::vector<LPCConfItem>::iterator iter;
	printf("test print config item begin=====\n");
	for (iter = m_configItemList.begin(); iter != m_configItemList.end(); ++iter)
	{
		printf("#%s# : #%s#\n", (*iter)->ItemName, (*iter)->ItemContent);
	}
	printf("test print config item end=====\n");
}
